/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package toolsKit.csv;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 *
 * @author mathieubakrim
 */
public class CsvFileWriterImpl implements  CsvFileWriter{
    private File file;
    private char separator;
    
    private CsvFileWriterImpl(){
        super();
    }
    
    public CsvFileWriterImpl(File file){
        this(file, ';');
    }
    
    public CsvFileWriterImpl(File file, char separator){
        if (file == null){
            throw new IllegalArgumentException("File cannot be null");
        }
        
        this.file = file;
        this.separator = separator;
    }
    
    private void writeEmptyFile(){
        System.out.println("Empty file");
    }

    @Override
    public void write(List<Map<String, String>> mappedData) {
        if (mappedData == null) {
			throw new IllegalArgumentException("List cannot be null");
		}

		if (mappedData.isEmpty()) {
			writeEmptyFile();
		}
		final Map<String, String> oneData = mappedData.get(0);

		final String[] titles = new String[oneData.size()]; // (String[])
															// oneData.keySet().toArray();
		int i = 0;
		for (String key : oneData.keySet()) {
			titles[i++] = key;
		}
		write(mappedData, titles);
    }

    @Override
    public void write(List<Map<String, String>> mappedData, String[] titles) {
        if (mappedData == null) {
			throw new IllegalArgumentException("list cannot be null");
		}

		if (titles == null) {
			throw new IllegalArgumentException("list cannot be null");
		}

		if (mappedData.isEmpty()) {
			writeEmptyFile();
		}

		FileWriter fw = null;
		BufferedWriter bw = null;

		try {
			fw = new FileWriter(file);
			bw = new BufferedWriter(fw);

			// Headers
			boolean first = true;
			for (String title : titles) {
				if (first) {
					first = false;
				} else {
					bw.write(separator);
				}
				write(title, bw);
			}
			bw.write("\n");

			// data
			for (Map<String, String> oneData : mappedData) {
				first = true;
				for (String title : titles) {
					if (first) {
						first = false;
					} else {
						bw.write(separator);
					}
					final String value = oneData.get(title);
					write(value, bw);

				}
				bw.write("\n");
			}

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (bw != null) {
				try {
					bw.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}

			if (fw != null) {
				try {
					fw.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	private void write(String value, BufferedWriter bw) throws IOException {

		if (value == null) {
			value = "";
		}

		boolean needQuote = false;

		if (value.indexOf("\n") != -1) {
			needQuote = true;
		}

		if (value.indexOf(separator) != -1) {
			needQuote = true;
		}
		
		if (value.indexOf("\"") != -1) {
			needQuote = true;
			value = value.replaceAll("\"", "\"\"");
		}
		
		if(needQuote) {
			value = "\"" + value + "\"";
		}

		bw.write(value);
	}
    
    
    
    
}
